/*
切片slice
其本身并不是数组，它指向底层的数组
作为变长数组的替代方案，可以关联底层数组的局部或全部
为引用类型
可以直接创建，或从底层数组获取生成
使用len()获取元素个数，用cap()获取容量
一般使用make()创建
如果多个slice指向相同底层数组，其中一个的值改变会影响全部
make([]T,len,cap)len表示存数的元素个数，cap表示容量。其中cap省略则值跟len相同

append
可以在slice尾部追加元素
可以将一个slice追加在另一个slice尾部
如果最终长度未超过追加到的slice的容量则返回原始slice，否则重新分配数组并拷贝原始数据
*/
package main

import (
	"fmt"
)

func main() {
	fmt.Println("-----------------slice的[]声明-----------------------")
	a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	fmt.Println(a)
	var slice_1 []int //slice的声明
	fmt.Println(slice_1)
	//a[sartPos,endPos] endPos为截止位置，不会被取到，endPos也可以理解为取到第endPos个
	slice_1 = a[5:10]
	fmt.Println("获取数组a下标5到第10个元素", slice_1)
	slice_1 = a[:5]
	fmt.Println("获取数组a的前五个元素", slice_1)
	slice_1 = a[4:]
	fmt.Println("获取数组a从下标4开始的所有元素", slice_1)
	slice_1 = a[:]
	fmt.Println("获取数组a的所有元素", slice_1)
	fmt.Println("-----------------slice的make声明,append使用，copy的使用-----------------------")
	slice_mk := make([]int, 3, 6)
	fmt.Println(len(slice_mk), cap(slice_mk))
	fmt.Printf("%v %p\n", slice_mk, slice_mk)
	slice_mk1 := append(slice_mk, 1, 2, 3)
	fmt.Printf("%v %p:The length is not greater than cap, the address is not changed!\n", slice_mk1, slice_mk1)
	slice_mk1[0] = 10
	fmt.Println(slice_mk, slice_mk1, ":using the same array address,so the element change at the same time.")
	slice_mk2 := append(slice_mk1, 4, 5, 6)
	fmt.Printf("%v %p:The length is greater than cap, the address is changed!\n", slice_mk2, slice_mk2) //此时slice_mk已经指向新的数组了
	slice_mk2[0] = 100
	fmt.Println(slice_mk1, slice_mk2, ":using the different array address,so one array element change do not affect annother")

	slice_mk = make([]int, 3) //cap不设置默认为len的值
	fmt.Println(len(slice_mk), cap(slice_mk))

	slice_mk1 = []int{1, 2, 3, 4, 5, 6}
	slice_mk2 = []int{7, 8, 9}
	copy(slice_mk1, slice_mk2) //copy(dest,source) 拷贝范围取交集（两个slice中最小的len），
	fmt.Println(slice_mk1)
	slice_mk1 = []int{1, 2, 3, 4, 5, 6}
	copy(slice_mk2, slice_mk1)
	fmt.Println(slice_mk2)
	slice_mk2 = []int{7, 8, 9}
	copy(slice_mk1[2:3], slice_mk2[1:3]) //dest的长度为1，source的长度为2，len最小为1，只复制source的第一个元素到dest
	fmt.Println(slice_mk1)

	fmt.Println("-----------------reslice-----------------------")
	slice_byte1 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
	slice_byte2 := slice_byte1[2:5]
	fmt.Println(string(slice_byte2), len(slice_byte2), cap(slice_byte2)) //len = 5-2,cap = 11-2
	slice_byte3 := slice_byte1[3:5]                                      //从slice_byte1生成slice_byte3
	//	slice_byte3 := slice_byte2[1:3]	 //从slice_byte2生成slice_byte3 startPos，endPos不能超过cap值,但index不能超过len-1
	fmt.Println(string(slice_byte3), len(slice_byte3), cap(slice_byte3)) //len = 5-3,cap = 11-3
	slice_byte3[1] = '0'                                                 //修改元素会影响到底层数组和指向数组的slice
	fmt.Println(string(slice_byte1), string(slice_byte2), string(slice_byte3))
	slice_byte3[1] = 'e'

	slice_byte3 = slice_byte2[3:8]
	fmt.Println(string(slice_byte3), len(slice_byte3), cap(slice_byte3))

	fmt.Println("-----------------classroom work-----------------------")
	/*
		使slice3指向slice2的完整元素
	*/
	slice_2 := [...]int{1, 2, 3, 4, 5, 6}
	fmt.Println(slice_2)
	slice_3 := slice_2 //method1
	fmt.Println(slice_3)
	slice_4 := slice_2[:cap(slice_2)] //method2
	fmt.Println(slice_4)
	slice_5 := slice_2[:] //method3
	fmt.Println(slice_5)
	slice_6 := make([]int, cap(slice_2))
	copy(slice_6, slice_2[:cap(slice_2)]) //method4
	fmt.Println(slice_6)

}
